#include "youdaoservice.h"
#include <DNotifySender>

DCORE_USE_NAMESPACE

YoudaoService::YoudaoService(QObject *parent) : QObject(parent) {
  loadSettings();

  dialog = new TransDialog;
  net = new QNetworkAccessManager(this);
  connect(net, &QNetworkAccessManager::finished, this,
          [=](QNetworkReply *reply) {
            if (reply && reply->error() == QNetworkReply::NoError) {
              QByteArray data = reply->readAll();
              this->parse(data);
            } else {
              DUtil::DNotifySender sender(tr("Request Youdao API Error"));
              sender.appIcon("dialog-error");
              sender.timeOut(1000);
              sender.appName(tr("YoudaoTrans"));
              sender.call();
            }
            reply->close();
          });

  sm = new SettingDialog(m_enabled, m_sel, m_cp);
  connect(sm, &SettingDialog::sigCpEnabled, this, [=](bool v) { m_cp = v; });
  connect(sm, &SettingDialog::sigSelEnabled, this, [=](bool v) { m_sel = v; });
  connect(sm, &SettingDialog::sigEnabled, this, [=](bool v) { m_enabled = v; });
}

YoudaoService::~YoudaoService() { dialog->deleteLater(); }

bool YoudaoService::enabled() const { return m_enabled; }

void YoudaoService::setEnabled(bool enabled) {
  sm->setYoudaoEnabled(enabled);
  DUtil::DNotifySender sender((enabled ? tr("Enable") : tr("Disalbe")) +
                              tr("Success"));
  sender.appIcon(m_enabled ? "dialog-ok" : "dialog-warning");
  sender.timeOut(1000);
  sender.appName(tr("YoudaoTrans"));
  sender.call();
}

void YoudaoService::translate(QString word) {
  if (m_enabled && isVaildWord(word))
    net->get(QNetworkRequest(
        QUrl("http://dict.youdao.com/fsearch?client=deskdict&q=" +
             QUrl::toPercentEncoding(word) +
             "&pos=-1&doctype=xml&xmlVersion=3.2&dogVersion=1.0&"
             "vendor=unknown&appVer=3.1.17.4208&le=eng")));
}

void YoudaoService::toggle() { setEnabled(!enabled()); }

void YoudaoService::parse(QByteArray &content) {
  QDomDocument dom;
  QString errstr;
  int row, col;
  if (!dom.setContent(content, false, &errstr, &row, &col)) {
    return;
  }

  auto doc = dom.documentElement();
  if (doc.tagName() != "yodaodict")
    return;

  auto nodeList = doc.childNodes();
  auto len = nodeList.size();

  if (len) {
    QString word, ukphonetic, usphonetic, trans, youtrans;

    for (auto i = 0; i < len; i++) {
      auto node = nodeList.at(i).toElement();
      auto name = node.tagName();

      if (name == "return-phrase") {
        word = node.text();
      } else if (name == "uk-phonetic-symbol") {
        ukphonetic = node.text();
      } else if (name == "us-phonetic-symbol") {
        usphonetic = node.text();
      } else if (name == "custom-translation") {
        trans = parseCustomTrans(node);
      } else if (name == "yodao-web-dict") {
        youtrans = parseYoudaoTrans(node);
      }
    }

    QString content;
    if (trans.length()) {
      content = trans;
      if (youtrans.length()) {
        content += "\n\n---\n\n" + youtrans;
      }
    } else {
      content = youtrans;
    }

    dialog->setInfo(word, ukphonetic, usphonetic, content);
    dialog->popup();
  }
}

QString YoudaoService::parseCustomTrans(QDomElement &ele) {
  auto nodeList = ele.childNodes();
  auto len = nodeList.size();
  QStringList content;
  if (len) {
    for (auto i = 0; i < len; i++) {
      auto node = nodeList.at(i).toElement();
      auto name = node.tagName();
      if (name == "translation") {
        content << node.firstChild().toElement().text();
      }
    }
    return content.join("\n\n");
  } else {
    return QString();
  }
}

QString YoudaoService::parseYoudaoTrans(QDomElement &ele) {
  auto nodeList = ele.childNodes();
  auto len = nodeList.size();
  QStringList content;
  if (len) {
    for (auto i = 0; i < len; i++) {
      QString key;
      QStringList trans;
      auto node = nodeList.at(i).toElement();
      auto nodes = node.childNodes();
      auto count = nodes.size();
      for (auto y = 0; y < count; y++) {
        auto inode = nodes.at(y).toElement();
        auto name = inode.tagName();
        if (name == "trans") {
          trans << inode.firstChild().toElement().text();
        } else if (name == "key") {
          key = inode.text();
        }
      }
      content << "### " + key + "\n\n* " + trans.join("\n\n* ");
    }
    return content.join("\n\n");
  } else {
    return QString();
  }
}

bool YoudaoService::isVaildWord(QString &word) {
  word = word.trimmed();
  if (word.isEmpty())
    return false;
  for (auto &c : word) {
    if (!((c >= 'a' && c <= 'z') || (c >= 'A' && c <= 'Z') || c == '-' ||
          c == ' '))
      return false;
  }
  return true;
}

void YoudaoService::showSettings() { sm->exec(); }

bool YoudaoService::sel() const { return m_sel; }

void YoudaoService::loadSettings() {
  QSettings settings("WingCloud", "YoudaoTrans");
  m_cp = settings.value("enablecp", true).toBool();
  m_sel = settings.value("enablesel", true).toBool();
  m_enabled = settings.value("enabled", true).toBool();
}

void YoudaoService::saveSettings() {
  QSettings settings("WingCloud", "YoudaoTrans");
  settings.setValue("enablecp", m_cp);
  settings.setValue("enablesel", m_sel);
  settings.setValue("enabled", m_enabled);
}

bool YoudaoService::cp() const { return m_cp; }
